#ifndef REGISTROMF_H_
#define REGISTROMF_H_

#include <string>
#include <vector>
#include <fstream>
using namespace std;

//Definiciones de largos maximos por campo en bytes
#define M_TITULO 1
#define M_VEC_AU 1
#define M_AUTOR 1
#define M_ANIO 1
#define M_IDIOM 1
#define M_LETRA 4

/**
 * @class RegistroMF RegistroMF.h "idxMasterfile/RegistroMF.h"
 * @brief Registro que contiene los datos correspondientes a una cancion
 */
class RegistroMF
{
	public:
		/**
		 * @brief Constructor por defecto, deja los atributos con su constructor por defecto
		 */
		RegistroMF();
		/**
		 * @brief Construye un registro a partir de un archivo de texto de formato:
		 * 1ra línea: Autor-Año de grabación-título-idioma del tema
		 * Otras lineas: Letra
		 * @param archivo Archivo abierto en modo texto
		 */
		RegistroMF(istream &archivo);
		/**
		 * @brief Construye un registro a partir de una tira de bytes y una longitud
		 */
		RegistroMF(const char* tiraBytes, const size_t tam);
		/**
		 * @brief Contruye un registro a partir de los parametros dados
		 */
		RegistroMF(const string titulo, const vector<string> autores,
				const string idioma, const string anio, const string letra);
		/**
		 * @brief Contruye un registro a partir de los parametros dados
		 */
		RegistroMF(const char* titulo, const vector<string> autores,
				const char* idioma, const char* anio, const char* letra);
		/**
		 * @brief Carga un registro a partir de una tira de bytes y una longitud
		 */
		void cargar(const char* tiraBytes, const size_t tam);
		/**
		 * @brief Carga un registro a partir de un archivo de texto de formato:
		 * 1ra línea: Autor-Año de grabación-título-idioma del tema
		 * Otras lineas: Letra
		 * @param archivo Archivo abierto en modo texto
		 */
		void cargar(istream &archivo);
		/**
		 * @brief convierte la clase en una tira de bytes
		 * @param buffer puntero donde se guardaran los datos
		 * @return el largo de bytes usados
		 * @post el buffer esta en memoria dinamica y debe ser liberado por el usuario
		 */
		size_t serializar(char *& buffer);
		/**
		 * @brief Calcula el espacio que ocuparia una representasion serializada
		 * @return el tamanio que ocuparia
		 */
		size_t tamSerializado();
		/**
		 * @brief compara si son iguales los autores el idioma y el titulo
		 */
		bool igualdadParcial(const RegistroMF &otro);
		/**
		 * @brief Devuelve un string
		 * @param dest String donde se guardara
		 */
		void sCabecera(string &dest);
		string titulo;
		vector<string> autores;
		string idioma;
		string anio;
		string letra;
		friend ostream& operator<<(ostream& os, const RegistroMF &reg);
	private:
		/**
		 * @brief Copia una serie de bytes poniendo un prefijo de longitud delante
		 * @param destino Array destino
		 * @param origen Array origen
		 * @param tam Longitud de byes a copiar
		 * @param preBytes Cantidad de bytes a usar como prefijo
		 * @param offset A partir de donde agregar los nuevos bytes
		 * @post El offset fue corrido y los bytes copiados
		 */
		void memcpyPrefij(char* destino, const char* origen, size_t tam, size_t preBytes, size_t *offset);
		/**
		 * @brief dada una tira de bytes y
		 * @param destino
		 * @param origen
		 * @param preBytes
		 * @param offset
		 * @post El offset fue corrido y el string tiene el dato
		 */
		void aString(string &destino, const char* origen, size_t preBytes, size_t &offset);
};

bool operator==(const RegistroMF &A, const RegistroMF &B);

#endif /* REGISTROMF_H_ */
